<html>
<head><title>Calculator</title></head>
<body>

<h1>Calculator</h1>

Type an expression in the following box (e.g., 10.5+20*3/25).
<p>
<form method="GET">
<input type="text" name="expr"><input type="submit" value="Calculate">
</form>
</p>

<ul>
    <li>Only numbers and +,-,* and / operators are allowed in the expression. 
    <li>The evaluation follows the standard operator precedence.
    <li>The calculator does not support parentheses.
</ul>

<?php
	if ($_GET["expr"] != NULL)
	{
		echo "<h2>Result</h2>";	
		
		$expr = $_GET["expr"];
		
		// Check that there are no digits separated by white space (or decimals surrounded by whitespace)
		// Cases:           "9  9"    " . " " ."     ". "
		$digitSpaced = "#(\d\s+\d)|(\s+\.(\s+|$))|(^\.\s+)#";
		if (preg_match($digitSpaced, $expr))
			exit("Invalid input expression: " . $_GET["expr"]);
			
		// Get rid of all whitespaces
		$expr = preg_replace("/\s/", "", $expr);
		
		$operator = "[-+*/]";		
		
		// Check for case when multiple -- in beginning 3 or more elsewhere, or a * or /
		if (preg_match("#(^--)|(---)|(^\*)|(^/)#", $expr))
			exit("Invalid input expression: " . $_GET["expr"]);
			
		// Check for division by zero
		$zero = "(?:0+(?:[.]0+)?)";
		$zeroDivision = "#/((" . $zero . $operator .")|" . $zero . "$)#";
		//$zeroDivision = "#/(((?:0+(?:[.]0+)?)(?:[-+*/]))|(?:0+(?:[.]0+)?)$)#";
		if (preg_match($zeroDivision, $expr))
			exit("Invalid input expression: " . $_GET["expr"]);
		
		// Change sequence of two - to one +
		$expr = preg_replace("/--/", "+", $expr);
		
		// Check for invalid operator sequence and invalid symbols
		if (preg_match("#(" . $operator . "[+*/])|([^0-9-+*/.])#", $expr))
			exit("Invalid input expression: " . $_GET["expr"]);
		
		// Check for misuse of decimal
		// cases:           . 0  . /           -.+     /.       .      .+
		if (preg_match("#(\.[^0-9-+*/])|([-+*/]\.([^0-9]|$))|(^\.$)|(^\.[^0-9])#", $expr))
			exit("Invalid input expression: " . $_GET["expr"]);
		
		$number = "(?:\d+(?:[.]\d+)?)";
		$regex = "#(-?" . $number . "(?:" . $operator . "-?" . $number . ")?)$#"; //does ^ at beginning do anything?
		//$regex = "#^(?:\d+(?:[.]\d+)?)(?:[-+*/](?:\d+(?:[.]\d+)?))?#";
		if (preg_match($regex, $expr, $matches))
		{
			eval("\$answer = $expr;");
			echo $_GET["expr"] . " = " . $answer;
		}
		else
			echo "Invalid input expression: " . $_GET["expr"];	
	}
?>

</body>
</html>